/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.muni.fi.pb138.videolibrary.GUI;

import cz.muni.fi.pb138.videolibrary.database.Category;
import cz.muni.fi.pb138.videolibrary.database.DatabaseManager;
import cz.muni.fi.pb138.videolibrary.database.Medium;
import cz.muni.fi.pb138.videolibrary.exception.ElementAlreadyExistsException;
import cz.muni.fi.pb138.videolibrary.exception.WrongNumberOfElementsException;
import java.awt.Cursor;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.NoSuchElementException;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.SwingWorker;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.xpath.XPathExpressionException;
import org.xml.sax.SAXException;

/**
 *
 * @author peter_000
 */
public class videolibrary extends javax.swing.JFrame {

    public static final String CREATE = "Create";
    public static final String UPDATE = "Update";
    private static DatabaseManager manager = null;
    private long editingMediumId;
    private long editingCategoryId;
    private MediaTableModel mediaTableModel;
    private CategoriesTableModel categoriesTableModel;

    /**
     * Creates new form videolibrary
     */
    public videolibrary() {
        try {
            manager = new DatabaseManager(new File("database.xml"));
        } catch (ParserConfigurationException | SAXException | IOException | WrongNumberOfElementsException ex) {
            error("Cannot open database!");
            System.exit(1);
        }

        initComponents();

        mediaTableModel = new MediaTableModel(getAllMedia());
        mediumTable.setModel(mediaTableModel);

        mediumTable.addKeyListener(
                new KeyAdapter() {
                    @Override
                    public void keyPressed(KeyEvent e) {
                        int key = e.getKeyCode();
                        if (key != 127) // delete
                        {
                            return;
                        }
                        if (mediumTable.getSelectedRow() == -1) {
                            return;
                        }

                        int[] rows = mediumTable.getSelectedRows();
                        long[] ids = new long[rows.length];
                        for (int i = 0; i < ids.length; i++) {
                            ids[i] = (long) mediaTableModel.getValueAt(rows[i], 0);
                        }
                        DeleteMediaWorker deleteMedia = new DeleteMediaWorker(ids);
                        deleteMedia.execute();
                    }
                }
        );
        mediumTable.addMouseListener(
                new MouseAdapter() {
                    @Override
                    public void mouseClicked(MouseEvent e
                    ) {
                        if (e.getClickCount() == 2) {
                            updateSelectedMedium();
                        }
                    }
                }
        );

        categoriesTableModel = new CategoriesTableModel(getAllCategories());

        categoryTable.setModel(categoriesTableModel);

        categoryTable.addKeyListener(
                new KeyAdapter() {
                    @Override
                    public void keyPressed(KeyEvent e
                    ) {
                        int key = e.getKeyCode();
                        if (key != 127) // delete
                        {
                            return;
                        }
                        if (categoryTable.getSelectedRow() == -1) {
                            return;
                        }

                        int[] rows = categoryTable.getSelectedRows();
                        long[] ids = new long[rows.length];
                        for (int i = 0; i < ids.length; i++) {
                            ids[i] = (long) categoriesTableModel.getValueAt(rows[i], 0);
                        }
                        DeleteCategoriesWorker deleteCategories = new DeleteCategoriesWorker(ids);
                        deleteCategories.execute();
                    }
                }
        );
        categoryTable.addMouseListener(
                new MouseAdapter() {
                    @Override
                    public void mouseClicked(MouseEvent e
                    ) {
                        if (e.getClickCount() == 2) {
                            updateSelectedCategory();
                        }
                    }
                }
        );
    }

    /**
     * @brief Otvori okno s chybovou spravou
     * @param message chybova sprava
     */
    private void error(String message) {
        JOptionPane.showMessageDialog(null, message, "Error", JOptionPane.ERROR_MESSAGE);
    }

    /**
     * @brief ulozi databazu
     */
    private void save() {
        try {
            manager.serializetoXML(new File("database.xml"));
        } catch (IOException | TransformerException ex) {
            error("Cannot save database!");
        }
    }

    /**
     * @brief upravi oznacene medium
     */
    private void updateSelectedMedium() {
        int row = mediumTable.getSelectedRow();
        if (row == -1) {
            return;
        }
        try {
            Medium medium = manager.getMedium(editingMediumId = (Long) mediaTableModel.getValueAt(row, 0));
            titleLine.setText(medium.getTitle());
            authorLine.setText(medium.getAuthor());
            contentLine.setText(medium.getContent());
            languagesCombobox.removeAllItems();
            categoriesCombobox.removeAllItems();
            for (int i = 0; i < medium.getAllLanguage().size(); i++) {
                languagesCombobox.addItem(medium.getAllLanguage().get(i));
            }
            for (int i = 0; i < medium.getAllCategory().size(); i++) {
                categoriesCombobox.addItem(medium.getAllCategory().get(i));
            }
            updateMediumButton.setText(UPDATE);
            mediumEdit.setVisible(true);
            mediumEdit.pack();
        } catch (XPathExpressionException | NoSuchElementException | WrongNumberOfElementsException ex) {
            error("Cannot show medium!");
        }
    }

    /**
     * @brief upravi oznacenu kategoriu
     */
    private void updateSelectedCategory() {
        int row = categoryTable.getSelectedRow();
        if (row == -1) {
            return;
        }
        try {
            Category category = manager.getCategory(editingCategoryId = (Long) categoriesTableModel.getValueAt(row, 0));

            titleCategoryLine.setText(category.getTitle());
            mediaCombobox.removeAllItems();
            for (int i = 0; i < category.getAllMedia().size(); i++) {
                mediaCombobox.addItem(category.getAllMedia().get(i).getTitle());
            }
            updateCategoryButton.setText(UPDATE);
            categoryEdit.setVisible(true);
            categoryEdit.pack();
        } catch (XPathExpressionException | NoSuchElementException | WrongNumberOfElementsException ex) {
            error("Cannot show category!");
        }
    }

    /**
     * @brief ukonci aplikaciu
     */
    private void close() {
        save();
        System.exit(0);
    }

    /**
     * @brief nastavi busy stav podla parametra
     * @param state stav
     */    
    private void busy(boolean state) {
        if (state) {
            this.setCursor(new Cursor(Cursor.WAIT_CURSOR));
        } else {
            this.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
        }
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        mediumEdit = new javax.swing.JDialog();
        jLabel1 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        jLabel3 = new javax.swing.JLabel();
        jLabel5 = new javax.swing.JLabel();
        jLabel6 = new javax.swing.JLabel();
        titleLine = new javax.swing.JTextField();
        authorLine = new javax.swing.JTextField();
        contentLine = new javax.swing.JTextField();
        languagesCombobox = new javax.swing.JComboBox();
        categoriesCombobox = new javax.swing.JComboBox();
        addLanguageButton = new javax.swing.JButton();
        removeLanguageButton = new javax.swing.JButton();
        addToCategoryButton = new javax.swing.JButton();
        removeFromCategoryButton = new javax.swing.JButton();
        updateMediumButton = new javax.swing.JButton();
        newLanguageDialog = new javax.swing.JDialog();
        jLabel4 = new javax.swing.JLabel();
        newLanguageLine = new javax.swing.JTextField();
        confirmLanguageButton = new javax.swing.JButton();
        categoryEdit = new javax.swing.JDialog();
        jLabel7 = new javax.swing.JLabel();
        titleCategoryLine = new javax.swing.JTextField();
        updateCategoryButton = new javax.swing.JButton();
        jLabel8 = new javax.swing.JLabel();
        mediaCombobox = new javax.swing.JComboBox();
        addMediumButton = new javax.swing.JButton();
        removeMediumButton = new javax.swing.JButton();
        chooseDialog = new javax.swing.JDialog();
        jScrollPane3 = new javax.swing.JScrollPane();
        itemList = new javax.swing.JList();
        confirmButton = new javax.swing.JButton();
        jTabbedPane = new javax.swing.JTabbedPane();
        mediaPanel = new javax.swing.JPanel();
        jScrollPane1 = new javax.swing.JScrollPane();
        mediumTable = new javax.swing.JTable();
        addMediumLabel = new javax.swing.JLabel();
        mediumTitleLine = new javax.swing.JTextField();
        mediumConfirmButton = new javax.swing.JButton();
        searchMediaLine = new javax.swing.JTextField();
        categoriesPanel = new javax.swing.JPanel();
        searchCategoriesLine = new javax.swing.JTextField();
        addCategoryLabel = new javax.swing.JLabel();
        categoryConfirmButton = new javax.swing.JButton();
        categoryTitleLine = new javax.swing.JTextField();
        jScrollPane2 = new javax.swing.JScrollPane();
        categoryTable = new javax.swing.JTable();
        jMenuBar1 = new javax.swing.JMenuBar();
        fileMenu = new javax.swing.JMenu();
        importMenuItem = new javax.swing.JMenuItem();
        saveMenuItem = new javax.swing.JMenuItem();
        refreshMenuItem = new javax.swing.JMenuItem();
        exitMenuItem = new javax.swing.JMenuItem();
        editMenu = new javax.swing.JMenu();
        createMenu = new javax.swing.JMenu();
        jMenuItem1 = new javax.swing.JMenuItem();
        jMenuItem2 = new javax.swing.JMenuItem();
        updateMenuItem = new javax.swing.JMenuItem();
        deleteMenuItem = new javax.swing.JMenuItem();
        helpMenu = new javax.swing.JMenu();
        aboutMenuItem = new javax.swing.JMenuItem();

        mediumEdit.setTitle("Medium");
        mediumEdit.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
        mediumEdit.setLocationByPlatform(true);
        mediumEdit.setName("dialog"); // NOI18N

        jLabel1.setText("Title:");

        jLabel2.setText("Author:");

        jLabel3.setText("Content:");

        jLabel5.setText("Languages:");

        jLabel6.setText("Categories:");

        addLanguageButton.setText("+");
        addLanguageButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                addLanguageButtonActionPerformed(evt);
            }
        });

        removeLanguageButton.setText("-");
        removeLanguageButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                removeLanguageButtonActionPerformed(evt);
            }
        });

        addToCategoryButton.setText("+");
        addToCategoryButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                addToCategoryButtonActionPerformed(evt);
            }
        });

        removeFromCategoryButton.setText("-");
        removeFromCategoryButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                removeFromCategoryButtonActionPerformed(evt);
            }
        });

        updateMediumButton.setText("Update");
        updateMediumButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                updateMediumButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout mediumEditLayout = new javax.swing.GroupLayout(mediumEdit.getContentPane());
        mediumEdit.getContentPane().setLayout(mediumEditLayout);
        mediumEditLayout.setHorizontalGroup(
            mediumEditLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(mediumEditLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(mediumEditLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(mediumEditLayout.createSequentialGroup()
                        .addGroup(mediumEditLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jLabel1)
                            .addComponent(jLabel2)
                            .addComponent(jLabel3)
                            .addComponent(jLabel5)
                            .addComponent(jLabel6))
                        .addGap(51, 51, 51)
                        .addGroup(mediumEditLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(contentLine)
                            .addComponent(authorLine)
                            .addComponent(titleLine)
                            .addGroup(mediumEditLayout.createSequentialGroup()
                                .addGroup(mediumEditLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                                    .addComponent(categoriesCombobox, 0, 120, Short.MAX_VALUE)
                                    .addComponent(languagesCombobox, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addGroup(mediumEditLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addComponent(addLanguageButton)
                                    .addComponent(addToCategoryButton))
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addGroup(mediumEditLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addComponent(removeLanguageButton)
                                    .addComponent(removeFromCategoryButton)))))
                    .addComponent(updateMediumButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addContainerGap())
        );
        mediumEditLayout.setVerticalGroup(
            mediumEditLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(mediumEditLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(mediumEditLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel1)
                    .addComponent(titleLine, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(18, 18, 18)
                .addGroup(mediumEditLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel2)
                    .addComponent(authorLine, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(18, 18, 18)
                .addGroup(mediumEditLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel3)
                    .addComponent(contentLine, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(18, 18, 18)
                .addGroup(mediumEditLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel5)
                    .addComponent(languagesCombobox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(addLanguageButton)
                    .addComponent(removeLanguageButton))
                .addGap(18, 18, 18)
                .addGroup(mediumEditLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel6)
                    .addComponent(categoriesCombobox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(addToCategoryButton)
                    .addComponent(removeFromCategoryButton))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(updateMediumButton)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        mediumEdit.getAccessibleContext().setAccessibleParent(mediaPanel);

        newLanguageDialog.setLocationByPlatform(true);

        jLabel4.setText("Language");

        confirmLanguageButton.setText("Add");
        confirmLanguageButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                confirmLanguageButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout newLanguageDialogLayout = new javax.swing.GroupLayout(newLanguageDialog.getContentPane());
        newLanguageDialog.getContentPane().setLayout(newLanguageDialogLayout);
        newLanguageDialogLayout.setHorizontalGroup(
            newLanguageDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(newLanguageDialogLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jLabel4)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(newLanguageDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(confirmLanguageButton, javax.swing.GroupLayout.DEFAULT_SIZE, 125, Short.MAX_VALUE)
                    .addComponent(newLanguageLine))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        newLanguageDialogLayout.setVerticalGroup(
            newLanguageDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(newLanguageDialogLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(newLanguageDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel4)
                    .addComponent(newLanguageLine, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(confirmLanguageButton)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        categoryEdit.setLocationByPlatform(true);

        jLabel7.setText("Title:");

        updateCategoryButton.setText("Update");
        updateCategoryButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                updateCategoryButtonActionPerformed(evt);
            }
        });

        jLabel8.setText("Media:");

        addMediumButton.setText("+");
        addMediumButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                addMediumButtonActionPerformed(evt);
            }
        });

        removeMediumButton.setText("-");
        removeMediumButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                removeMediumButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout categoryEditLayout = new javax.swing.GroupLayout(categoryEdit.getContentPane());
        categoryEdit.getContentPane().setLayout(categoryEditLayout);
        categoryEditLayout.setHorizontalGroup(
            categoryEditLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(categoryEditLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(categoryEditLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(updateCategoryButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addGroup(categoryEditLayout.createSequentialGroup()
                        .addGroup(categoryEditLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jLabel7)
                            .addComponent(jLabel8))
                        .addGap(36, 36, 36)
                        .addGroup(categoryEditLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(categoryEditLayout.createSequentialGroup()
                                .addComponent(mediaCombobox, 0, 160, Short.MAX_VALUE)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(addMediumButton)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(removeMediumButton))
                            .addComponent(titleCategoryLine))))
                .addContainerGap())
        );
        categoryEditLayout.setVerticalGroup(
            categoryEditLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(categoryEditLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(categoryEditLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel7)
                    .addComponent(titleCategoryLine, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(categoryEditLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel8)
                    .addComponent(mediaCombobox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(addMediumButton)
                    .addComponent(removeMediumButton))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(updateCategoryButton)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        chooseDialog.setLocationByPlatform(true);

        itemList.setToolTipText("");
        jScrollPane3.setViewportView(itemList);

        confirmButton.setText("Confirm");
        confirmButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                confirmButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout chooseDialogLayout = new javax.swing.GroupLayout(chooseDialog.getContentPane());
        chooseDialog.getContentPane().setLayout(chooseDialogLayout);
        chooseDialogLayout.setHorizontalGroup(
            chooseDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, chooseDialogLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(chooseDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jScrollPane3, javax.swing.GroupLayout.DEFAULT_SIZE, 376, Short.MAX_VALUE)
                    .addComponent(confirmButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addContainerGap())
        );
        chooseDialogLayout.setVerticalGroup(
            chooseDialogLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(chooseDialogLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane3, javax.swing.GroupLayout.DEFAULT_SIZE, 245, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(confirmButton)
                .addContainerGap())
        );

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Video library");
        setName("mainWindow"); // NOI18N
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                formWindowClosing(evt);
            }
        });

        jTabbedPane.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                jTabbedPaneStateChanged(evt);
            }
        });

        mediaPanel.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.LOWERED));

        mediumTable.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {

            },
            new String [] {

            }
        ));
        mediumTable.setMaximumSize(new java.awt.Dimension(32000, 32000));
        jScrollPane1.setViewportView(mediumTable);

        addMediumLabel.setText("Add medium");

        mediumTitleLine.setText("title");
        mediumTitleLine.setMinimumSize(new java.awt.Dimension(4, 25));
        mediumTitleLine.setPreferredSize(new java.awt.Dimension(28, 25));
        mediumTitleLine.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                mediumTitleLineFocusGained(evt);
            }
            public void focusLost(java.awt.event.FocusEvent evt) {
                mediumTitleLineFocusLost(evt);
            }
        });

        mediumConfirmButton.setText("confirm");
        mediumConfirmButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                mediumConfirmButtonActionPerformed(evt);
            }
        });

        searchMediaLine.setText("search");
        searchMediaLine.setMinimumSize(new java.awt.Dimension(47, 25));
        searchMediaLine.setPreferredSize(new java.awt.Dimension(47, 25));
        searchMediaLine.addCaretListener(new javax.swing.event.CaretListener() {
            public void caretUpdate(javax.swing.event.CaretEvent evt) {
                searchMediaLineCaretUpdate(evt);
            }
        });
        searchMediaLine.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                searchMediaLineFocusGained(evt);
            }
            public void focusLost(java.awt.event.FocusEvent evt) {
                searchMediaLineFocusLost(evt);
            }
        });

        javax.swing.GroupLayout mediaPanelLayout = new javax.swing.GroupLayout(mediaPanel);
        mediaPanel.setLayout(mediaPanelLayout);
        mediaPanelLayout.setHorizontalGroup(
            mediaPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(mediaPanelLayout.createSequentialGroup()
                .addGap(8, 8, 8)
                .addGroup(mediaPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(mediaPanelLayout.createSequentialGroup()
                        .addComponent(searchMediaLine, javax.swing.GroupLayout.PREFERRED_SIZE, 120, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(addMediumLabel)
                        .addGap(12, 12, 12)
                        .addComponent(mediumTitleLine, javax.swing.GroupLayout.PREFERRED_SIZE, 200, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(26, 26, 26)
                        .addComponent(mediumConfirmButton))
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 673, Short.MAX_VALUE))
                .addGap(8, 8, 8))
        );
        mediaPanelLayout.setVerticalGroup(
            mediaPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(mediaPanelLayout.createSequentialGroup()
                .addGap(8, 8, 8)
                .addGroup(mediaPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(searchMediaLine, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(addMediumLabel)
                    .addComponent(mediumTitleLine, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(mediumConfirmButton))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 299, Short.MAX_VALUE)
                .addGap(8, 8, 8))
        );

        jTabbedPane.addTab("Media", mediaPanel);

        categoriesPanel.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.LOWERED));

        searchCategoriesLine.setText("search");
        searchCategoriesLine.setMinimumSize(new java.awt.Dimension(47, 25));
        searchCategoriesLine.setPreferredSize(new java.awt.Dimension(47, 25));
        searchCategoriesLine.addCaretListener(new javax.swing.event.CaretListener() {
            public void caretUpdate(javax.swing.event.CaretEvent evt) {
                searchCategoriesLineCaretUpdate(evt);
            }
        });
        searchCategoriesLine.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                searchCategoriesLineFocusGained(evt);
            }
            public void focusLost(java.awt.event.FocusEvent evt) {
                searchCategoriesLineFocusLost(evt);
            }
        });

        addCategoryLabel.setText("Add category");

        categoryConfirmButton.setText("confirm");
        categoryConfirmButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                categoryConfirmButtonActionPerformed(evt);
            }
        });

        categoryTitleLine.setText("title");
        categoryTitleLine.setMinimumSize(new java.awt.Dimension(4, 25));
        categoryTitleLine.setPreferredSize(new java.awt.Dimension(39, 25));
        categoryTitleLine.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                categoryTitleLineFocusGained(evt);
            }
            public void focusLost(java.awt.event.FocusEvent evt) {
                categoryTitleLineFocusLost(evt);
            }
        });

        categoryTable.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {

            },
            new String [] {

            }
        ));
        categoryTable.setMaximumSize(new java.awt.Dimension(2147483647, 64000));
        jScrollPane2.setViewportView(categoryTable);

        javax.swing.GroupLayout categoriesPanelLayout = new javax.swing.GroupLayout(categoriesPanel);
        categoriesPanel.setLayout(categoriesPanelLayout);
        categoriesPanelLayout.setHorizontalGroup(
            categoriesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(categoriesPanelLayout.createSequentialGroup()
                .addGap(8, 8, 8)
                .addGroup(categoriesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(categoriesPanelLayout.createSequentialGroup()
                        .addComponent(searchCategoriesLine, javax.swing.GroupLayout.PREFERRED_SIZE, 120, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(addCategoryLabel)
                        .addGap(12, 12, 12)
                        .addComponent(categoryTitleLine, javax.swing.GroupLayout.PREFERRED_SIZE, 200, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(26, 26, 26)
                        .addComponent(categoryConfirmButton))
                    .addComponent(jScrollPane2))
                .addGap(8, 8, 8))
        );
        categoriesPanelLayout.setVerticalGroup(
            categoriesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(categoriesPanelLayout.createSequentialGroup()
                .addGap(8, 8, 8)
                .addGroup(categoriesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(searchCategoriesLine, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(addCategoryLabel)
                    .addComponent(categoryTitleLine, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(categoryConfirmButton))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 299, Short.MAX_VALUE)
                .addGap(8, 8, 8))
        );

        jTabbedPane.addTab("Categories", categoriesPanel);

        fileMenu.setText("File");

        importMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_I, java.awt.event.InputEvent.CTRL_MASK));
        importMenuItem.setText("Import");
        importMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                importMenuItemActionPerformed(evt);
            }
        });
        fileMenu.add(importMenuItem);

        saveMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_S, java.awt.event.InputEvent.CTRL_MASK));
        saveMenuItem.setText("Save");
        saveMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                saveMenuItemActionPerformed(evt);
            }
        });
        fileMenu.add(saveMenuItem);

        refreshMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_R, java.awt.event.InputEvent.CTRL_MASK));
        refreshMenuItem.setText("Refresh");
        refreshMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                refreshMenuItemActionPerformed(evt);
            }
        });
        fileMenu.add(refreshMenuItem);

        exitMenuItem.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_Q, java.awt.event.InputEvent.CTRL_MASK));
        exitMenuItem.setText("Exit");
        exitMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                exitMenuItemActionPerformed(evt);
            }
        });
        fileMenu.add(exitMenuItem);

        jMenuBar1.add(fileMenu);

        editMenu.setText("Edit");
        editMenu.addMenuListener(new javax.swing.event.MenuListener() {
            public void menuSelected(javax.swing.event.MenuEvent evt) {
                editMenuMenuSelected(evt);
            }
            public void menuDeselected(javax.swing.event.MenuEvent evt) {
            }
            public void menuCanceled(javax.swing.event.MenuEvent evt) {
            }
        });

        createMenu.setText("Add");

        jMenuItem1.setText("New Medium");
        jMenuItem1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItem1ActionPerformed(evt);
            }
        });
        createMenu.add(jMenuItem1);

        jMenuItem2.setText("New Category");
        jMenuItem2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItem2ActionPerformed(evt);
            }
        });
        createMenu.add(jMenuItem2);

        editMenu.add(createMenu);

        updateMenuItem.setText("Update");
        updateMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                updateMenuItemActionPerformed(evt);
            }
        });
        editMenu.add(updateMenuItem);

        deleteMenuItem.setText("Delete");
        deleteMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                deleteMenuItemActionPerformed(evt);
            }
        });
        editMenu.add(deleteMenuItem);

        jMenuBar1.add(editMenu);

        helpMenu.setText("Help");

        aboutMenuItem.setText("About");
        aboutMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                aboutMenuItemActionPerformed(evt);
            }
        });
        helpMenu.add(aboutMenuItem);

        jMenuBar1.add(helpMenu);

        setJMenuBar(jMenuBar1);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jTabbedPane)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jTabbedPane)
        );

        pack();
        setLocationRelativeTo(null);
    }// </editor-fold>//GEN-END:initComponents

    private void importMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_importMenuItemActionPerformed
        JFileChooser chooser = new JFileChooser();
        chooser.showDialog(this, null);

        new ImportWorker(chooser.getSelectedFile()).execute();
    }//GEN-LAST:event_importMenuItemActionPerformed

    private void exitMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exitMenuItemActionPerformed
        close();
    }//GEN-LAST:event_exitMenuItemActionPerformed

    private void formWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosing
        close();
    }//GEN-LAST:event_formWindowClosing

    private void saveMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveMenuItemActionPerformed
        save();
    }//GEN-LAST:event_saveMenuItemActionPerformed

    private void addLanguageButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addLanguageButtonActionPerformed
        newLanguageDialog.setVisible(true);
        newLanguageDialog.pack();
    }//GEN-LAST:event_addLanguageButtonActionPerformed

    private void removeLanguageButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_removeLanguageButtonActionPerformed
        if (languagesCombobox.getItemCount() == 0) {
            return;
        }

        languagesCombobox.removeItemAt(languagesCombobox.getSelectedIndex());
    }//GEN-LAST:event_removeLanguageButtonActionPerformed

    private void confirmLanguageButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_confirmLanguageButtonActionPerformed
        if (!newLanguageLine.getText().isEmpty()) {
            languagesCombobox.addItem(newLanguageLine.getText());
            newLanguageDialog.setVisible(false);
        }
    }//GEN-LAST:event_confirmLanguageButtonActionPerformed

    private void addToCategoryButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addToCategoryButtonActionPerformed
        chooseDialog.setTitle("Categories");
        ArrayList<String> items = new ArrayList<>();
        ArrayList<Category> c = getAllCategories();
        for (int i = 0; i < c.size(); i++) {
            String title = c.get(i).getTitle();
            if (((DefaultComboBoxModel) categoriesCombobox.getModel()).getIndexOf(title) == -1) {
                items.add(title);
            }
        }
        itemList.setListData(items.toArray());

        chooseDialog.setVisible(true);
        chooseDialog.pack();
    }//GEN-LAST:event_addToCategoryButtonActionPerformed

    private void removeFromCategoryButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_removeFromCategoryButtonActionPerformed
        if (categoriesCombobox.getItemCount() == 0) {
            return;
        }

        categoriesCombobox.removeItemAt(categoriesCombobox.getSelectedIndex());
    }//GEN-LAST:event_removeFromCategoryButtonActionPerformed

    private void updateMediumButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_updateMediumButtonActionPerformed
        Medium medium;
        String errorMsg = "";
        try {
            if (updateMediumButton.getText().equals(CREATE)) {
                errorMsg = "Cannot " + CREATE + " medium!";
                manager.addMedium(medium = new Medium(""));
            } else {
                errorMsg = "Cannot " + UPDATE + " medium!";
                medium = manager.getMedium(editingMediumId);
            }
            medium.setTitle(titleLine.getText());
            medium.setAuthor(authorLine.getText());
            medium.setContent(contentLine.getText());
            int allLangSize = medium.getAllLanguage().size();
            for (int i = 0; i < allLangSize; i++) {
                System.out.println(medium.getAllLanguage().get(0));
                medium.deleteLanguage(medium.getAllLanguage().get(0));
            }
            for (int i = 0; i < languagesCombobox.getItemCount(); i++) {
                medium.addLanguage((String) languagesCombobox.getItemAt(i));
            }

            for (int i = 0; i < medium.getAllCategory().size(); i++) {
                manager.removeFromCategories(medium);
            }
            for (int i = 0; i < categoriesCombobox.getItemCount(); i++) {
                manager.addToCategory(medium, manager.findCategory((String) categoriesCombobox.getItemAt(i)).get(0));
            }

            manager.updateMedium(medium);
            mediumEdit.setVisible(false);
            mediaTableModel.setMedia(getMedia());
        } catch (XPathExpressionException | NoSuchElementException |
                WrongNumberOfElementsException | ElementAlreadyExistsException ex) {
            error(errorMsg);
        }
    }//GEN-LAST:event_updateMediumButtonActionPerformed

    private void updateCategoryButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_updateCategoryButtonActionPerformed
        Category category;
        String errorMsg = "";
        try {
            if (updateCategoryButton.getText().equals(CREATE)) {
                errorMsg = "Cannot " + CREATE + " category!";
                manager.addCategory(category = new Category(""));
            } else {
                errorMsg = "Cannot " + UPDATE + " category!";
                category = manager.getCategory(editingCategoryId);
            }
            category.setTitle(titleCategoryLine.getText());

            for (int i = 0; i < category.getAllMedia().size(); i++) {
                manager.removeMediumFromCategory(category.getAllMedia().get(i), category);
            }

            for (int i = 0; i < mediaCombobox.getItemCount(); i++) {
                manager.addToCategory(manager.findMedium((String) mediaCombobox.getItemAt(i)).get(0), category);
            }

            manager.updateCategory(category);
            categoryEdit.setVisible(false);
            categoriesTableModel.setCategories(getCategories());
            mediaTableModel.setMedia(getMedia());
        } catch (NoSuchElementException | XPathExpressionException |
                WrongNumberOfElementsException | ElementAlreadyExistsException ex) {
            error(errorMsg);
        }
    }//GEN-LAST:event_updateCategoryButtonActionPerformed

    private void confirmButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_confirmButtonActionPerformed
        ArrayList<String> items = (ArrayList<String>) itemList.getSelectedValuesList();
        for (int i = 0; i < items.size(); i++) {
            if (chooseDialog.getTitle().equals("Media")) {
                mediaCombobox.addItem(items.get(i));
            } else {
                categoriesCombobox.addItem(items.get(i));
            }
        }

        chooseDialog.setVisible(false);
    }//GEN-LAST:event_confirmButtonActionPerformed

    private void addMediumButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addMediumButtonActionPerformed
        chooseDialog.setTitle("Media");
        ArrayList<String> items = new ArrayList<>();
        ArrayList<Medium> m = getAllMedia();
        for (int i = 0; i < m.size(); i++) {
            String title = m.get(i).getTitle();
            if (((DefaultComboBoxModel) mediaCombobox.getModel()).getIndexOf(title) == -1) {
                items.add(title);
            }
        }
        itemList.setListData(items.toArray());

        chooseDialog.setVisible(true);
        chooseDialog.pack();
    }//GEN-LAST:event_addMediumButtonActionPerformed

    private void removeMediumButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_removeMediumButtonActionPerformed
        if (mediaCombobox.getItemCount() == 0) {
            return;
        }

        mediaCombobox.removeItemAt(mediaCombobox.getSelectedIndex());
    }//GEN-LAST:event_removeMediumButtonActionPerformed

    private void refreshMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_refreshMenuItemActionPerformed
        RefreshWorker refresh = new RefreshWorker();
        refresh.execute();
    }//GEN-LAST:event_refreshMenuItemActionPerformed

    private void categoryTitleLineFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_categoryTitleLineFocusLost
        if (!categoryTitleLine.getText().isEmpty()) {
            return;
        }

        categoryTitleLine.setText("title");
        categoryTitleLine.setEditable(false);
    }//GEN-LAST:event_categoryTitleLineFocusLost

    private void categoryTitleLineFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_categoryTitleLineFocusGained
        if (!categoryTitleLine.getText().equals("title")) {
            return;
        }

        categoryTitleLine.setEditable(true);
        categoryTitleLine.getCaret().setVisible(true);
        categoryTitleLine.setText("");
    }//GEN-LAST:event_categoryTitleLineFocusGained

    private void categoryConfirmButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_categoryConfirmButtonActionPerformed
        try {
            String title = categoryTitleLine.getText().trim();
            if (!title.equals("")) {
                manager.addCategory(new Category(categoryTitleLine.getText()));
                categoriesTableModel.setCategories(getCategories());
            } else {
                error("Category should have some title!");
            }
            categoryTitleLine.setText("title");
        } catch (XPathExpressionException | WrongNumberOfElementsException | ElementAlreadyExistsException ex) {
            error("Cannot add category!");
        }
    }//GEN-LAST:event_categoryConfirmButtonActionPerformed

    private void searchCategoriesLineFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_searchCategoriesLineFocusLost
        if (!searchCategoriesLine.getText().isEmpty()) {
            return;
        }

        searchCategoriesLine.setText("search");
        searchCategoriesLine.setEditable(false);
    }//GEN-LAST:event_searchCategoriesLineFocusLost

    private void searchCategoriesLineFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_searchCategoriesLineFocusGained
        if (!searchCategoriesLine.getText().equals("search")) {
            return;
        }

        searchCategoriesLine.setEditable(true);
        searchCategoriesLine.getCaret().setVisible(true);
        searchCategoriesLine.setText("");
    }//GEN-LAST:event_searchCategoriesLineFocusGained

    private void searchCategoriesLineCaretUpdate(javax.swing.event.CaretEvent evt) {//GEN-FIRST:event_searchCategoriesLineCaretUpdate
        categoriesTableModel.setCategories(getCategories());
    }//GEN-LAST:event_searchCategoriesLineCaretUpdate

    private void mediumConfirmButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mediumConfirmButtonActionPerformed
        try {
            String title = mediumTitleLine.getText().trim();
            if (!title.equals("")) {
                manager.addMedium(new Medium(title));
                mediaTableModel.setMedia(getMedia());
            } else {
                error("Medium should have some title!");
            }
            mediumTitleLine.setText("title");
        } catch (XPathExpressionException | WrongNumberOfElementsException | ElementAlreadyExistsException ex) {
            error("Cannot add medium!");
        }
    }//GEN-LAST:event_mediumConfirmButtonActionPerformed

    private void mediumTitleLineFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_mediumTitleLineFocusLost
        if (!mediumTitleLine.getText().isEmpty()) {
            return;
        }

        mediumTitleLine.setText("title");
        mediumTitleLine.setEditable(false);
    }//GEN-LAST:event_mediumTitleLineFocusLost

    private void mediumTitleLineFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_mediumTitleLineFocusGained
        if (!mediumTitleLine.getText().equals("title")) {
            return;
        }

        mediumTitleLine.setEditable(true);
        mediumTitleLine.getCaret().setVisible(true);
        mediumTitleLine.setText("");
    }//GEN-LAST:event_mediumTitleLineFocusGained

    private void searchMediaLineFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_searchMediaLineFocusLost
        if (!searchMediaLine.getText().isEmpty()) {
            return;
        }

        searchMediaLine.setText("search");
        searchMediaLine.setEditable(false);
    }//GEN-LAST:event_searchMediaLineFocusLost

    private void searchMediaLineFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_searchMediaLineFocusGained
        if (!searchMediaLine.getText().equals("search")) {
            return;
        }

        searchMediaLine.setEditable(true);
        searchMediaLine.getCaret().setVisible(true);
        searchMediaLine.setText("");
    }//GEN-LAST:event_searchMediaLineFocusGained

    private void searchMediaLineCaretUpdate(javax.swing.event.CaretEvent evt) {//GEN-FIRST:event_searchMediaLineCaretUpdate
        mediaTableModel.setMedia(getMedia());
    }//GEN-LAST:event_searchMediaLineCaretUpdate

    private void jTabbedPaneStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_jTabbedPaneStateChanged
        mediaPanel.requestFocusInWindow();
        categoriesPanel.requestFocusInWindow();
    }//GEN-LAST:event_jTabbedPaneStateChanged

    private void editMenuMenuSelected(javax.swing.event.MenuEvent evt) {//GEN-FIRST:event_editMenuMenuSelected
        deleteMenuItem.setEnabled(false);
        updateMenuItem.setEnabled(false);
        if (jTabbedPane.getSelectedIndex() == 0) {
            if (mediumTable.getSelectedRow() != -1) {
                deleteMenuItem.setEnabled(true);
                updateMenuItem.setEnabled(true);
            }
        } else {
            if (categoryTable.getSelectedRow() != -1) {
                deleteMenuItem.setEnabled(true);
                updateMenuItem.setEnabled(true);
            }
        }
    }//GEN-LAST:event_editMenuMenuSelected

    private void deleteMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteMenuItemActionPerformed
        if (jTabbedPane.getSelectedIndex() == 0) {
            int[] rows = mediumTable.getSelectedRows();
            long[] ids = new long[rows.length];
            for (int i = 0; i < ids.length; i++) {
                ids[i] = (long) mediaTableModel.getValueAt(rows[i], 0);
            }
            DeleteMediaWorker deleteMedia = new DeleteMediaWorker(ids);
            deleteMedia.execute();
        } else {
            int[] rows = categoryTable.getSelectedRows();
            long[] ids = new long[rows.length];
            for (int i = 0; i < ids.length; i++) {
                ids[i] = (long) categoriesTableModel.getValueAt(rows[i], 0);
            }
            DeleteCategoriesWorker deleteCategories = new DeleteCategoriesWorker(ids);
            deleteCategories.execute();
        }
    }//GEN-LAST:event_deleteMenuItemActionPerformed

    private void updateMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_updateMenuItemActionPerformed
        if (jTabbedPane.getSelectedIndex() == 0) {
            updateSelectedMedium();
        } else {
            updateSelectedCategory();
        }
    }//GEN-LAST:event_updateMenuItemActionPerformed

    private void jMenuItem1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem1ActionPerformed
        titleLine.setText("");
        authorLine.setText("");
        contentLine.setText("");
        languagesCombobox.removeAllItems();
        categoriesCombobox.removeAllItems();
        updateMediumButton.setText(CREATE);
        mediumEdit.setVisible(true);
        mediumEdit.pack();
    }//GEN-LAST:event_jMenuItem1ActionPerformed

    private void jMenuItem2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem2ActionPerformed
        titleCategoryLine.setText("");
        mediaCombobox.removeAllItems();
        updateCategoryButton.setText(CREATE);
        categoryEdit.setVisible(true);
        categoryEdit.pack();
    }//GEN-LAST:event_jMenuItem2ActionPerformed

    private void aboutMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_aboutMenuItemActionPerformed
        JOptionPane.showMessageDialog(null, "Video Library - PB138 school project"
                + "\n\nCreated by:\nMartin Hatina\nDominika Hoďovská\n"
                + "Peter Franek\nKarel Vaculík", "About", JOptionPane.INFORMATION_MESSAGE);
    }//GEN-LAST:event_aboutMenuItemActionPerformed

    private class DeleteMediaWorker extends SwingWorker<Void, Void> {

        private final long[] ids;

        public DeleteMediaWorker(long[] ids) {
            this.ids = ids;
        }

        @Override
        protected Void doInBackground() {
            Medium m;
            for (long id : ids) {
                try {
                    m = manager.getMedium(id);
                    manager.removeFromCategories(m);
                    manager.deleteMedium(m);
                } catch (XPathExpressionException | NoSuchElementException | WrongNumberOfElementsException ex) {
                    error("Cannot delete medium!");
                }
            }
            return null;
        }

        @Override
        protected void done() {
            mediaTableModel.setMedia(getMedia());
        }
    }

    private class DeleteCategoriesWorker extends SwingWorker<Void, Void> {

        private final long[] ids;

        public DeleteCategoriesWorker(long[] ids) {
            this.ids = ids;
        }

        @Override
        protected Void doInBackground() {
            Category c;
            for (long id : ids) {
                try {
                    c = manager.getCategory(id);
                    manager.deleteCategory(c);
                } catch (XPathExpressionException | NoSuchElementException | WrongNumberOfElementsException ex) {
                    error("Cannot delete category!");
                }
            }
            return null;
        }

        @Override
        protected void done() {
            categoriesTableModel.setCategories(getCategories());
        }
    }

    private ArrayList<Medium> getMedia() {
        try {
            if (searchMediaLine.getText().isEmpty()
                    || searchMediaLine.getText().equals("search")) {
                return getAllMedia();
            }

            return (manager.findMedium(searchMediaLine.getText()));
        } catch (XPathExpressionException | NoSuchElementException | WrongNumberOfElementsException ex) {
            return new ArrayList<>();
        }
    }

    private ArrayList<Category> getCategories() {
        if (searchCategoriesLine.getText().isEmpty()
                || searchCategoriesLine.getText().equals("search")) {
            return getAllCategories();
        }
        try {
            return (manager.findCategory(searchCategoriesLine.getText()));
        } catch (XPathExpressionException | NoSuchElementException | WrongNumberOfElementsException ex) {
            return new ArrayList<>();

        }
    }

    private class ImportWorker extends SwingWorker {

        private final File file;

        public ImportWorker(File file) {
            this.file = file;
        }

        @Override
        protected Object doInBackground() throws Exception {
            busy(true);
            manager.importFrom(file);
            mediaTableModel.setMedia(getMedia());
            categoriesTableModel.setCategories(getCategories());
            busy(false);
            return null;
        }

    }

    private class RefreshWorker extends SwingWorker<Void, Void> {

        @Override
        protected Void doInBackground() {
            try {
                manager = new DatabaseManager(new File("database.xml"));
            } catch (ParserConfigurationException | SAXException | IOException | WrongNumberOfElementsException ex) {
                error("Cannot open database!");
                System.exit(1);
            }
            return null;
        }

        @Override
        protected void done() {
            mediaTableModel.setMedia(getAllMedia());
            categoriesTableModel.setCategories(getAllCategories());
        }
    }

    /**
     * @brief vrati vsetky media
     * @return zoznam medii
     */
    public static ArrayList<Medium> getAllMedia() {
        try {
            return manager.getAllMedia();
        } catch (XPathExpressionException | WrongNumberOfElementsException ex) {
            return null;
        }
    }

    /**
     * @brief vrati vsetky kategorie
     * @return zoznam kategorii
     */
    public static ArrayList<Category> getAllCategories() {
        try {
            return manager.getAllCategories();
        } catch (XPathExpressionException | WrongNumberOfElementsException ex) {
            return null;
        }
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JMenuItem aboutMenuItem;
    private javax.swing.JLabel addCategoryLabel;
    private javax.swing.JButton addLanguageButton;
    private javax.swing.JButton addMediumButton;
    private javax.swing.JLabel addMediumLabel;
    private javax.swing.JButton addToCategoryButton;
    private javax.swing.JTextField authorLine;
    private javax.swing.JComboBox categoriesCombobox;
    private javax.swing.JPanel categoriesPanel;
    private javax.swing.JButton categoryConfirmButton;
    private javax.swing.JDialog categoryEdit;
    private javax.swing.JTable categoryTable;
    private javax.swing.JTextField categoryTitleLine;
    private javax.swing.JDialog chooseDialog;
    private javax.swing.JButton confirmButton;
    private javax.swing.JButton confirmLanguageButton;
    private javax.swing.JTextField contentLine;
    private javax.swing.JMenu createMenu;
    private javax.swing.JMenuItem deleteMenuItem;
    private javax.swing.JMenu editMenu;
    private javax.swing.JMenuItem exitMenuItem;
    private javax.swing.JMenu fileMenu;
    private javax.swing.JMenu helpMenu;
    private javax.swing.JMenuItem importMenuItem;
    private javax.swing.JList itemList;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JLabel jLabel7;
    private javax.swing.JLabel jLabel8;
    private javax.swing.JMenuBar jMenuBar1;
    private javax.swing.JMenuItem jMenuItem1;
    private javax.swing.JMenuItem jMenuItem2;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JScrollPane jScrollPane3;
    private javax.swing.JTabbedPane jTabbedPane;
    private javax.swing.JComboBox languagesCombobox;
    private javax.swing.JComboBox mediaCombobox;
    private javax.swing.JPanel mediaPanel;
    private javax.swing.JButton mediumConfirmButton;
    private javax.swing.JDialog mediumEdit;
    private javax.swing.JTable mediumTable;
    private javax.swing.JTextField mediumTitleLine;
    private javax.swing.JDialog newLanguageDialog;
    private javax.swing.JTextField newLanguageLine;
    private javax.swing.JMenuItem refreshMenuItem;
    private javax.swing.JButton removeFromCategoryButton;
    private javax.swing.JButton removeLanguageButton;
    private javax.swing.JButton removeMediumButton;
    private javax.swing.JMenuItem saveMenuItem;
    private javax.swing.JTextField searchCategoriesLine;
    private javax.swing.JTextField searchMediaLine;
    private javax.swing.JTextField titleCategoryLine;
    private javax.swing.JTextField titleLine;
    private javax.swing.JButton updateCategoryButton;
    private javax.swing.JButton updateMediumButton;
    private javax.swing.JMenuItem updateMenuItem;
    // End of variables declaration//GEN-END:variables
}
